#define WIN32_LEAN_AND_MEAN
#include "GameView.h"

GameView::GameView()
{
}

GameView::~GameView()
{
}

bool GameView::configure()
{
	bool ret = BaseApplication::configure();


	int height = mWindow->getHeight();
    int width = mWindow->getWidth();

	gameControl=new GameControl;
	if (!gameControl->initMove())
		return false;

	gameControl->PassWindowParam(width,height);

	gameModel=new GameModel(gameControl);


	return ret;
}

void GameView::createScene()
{
	// a demo to show how skeletal animation works if joints must be moved by piece
    Ogre::Entity* ogre = mSceneMgr->createEntity("sinbad", "Sinbad.mesh");
    ogreNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    ogreNode->attachObject(ogre);

	Ogre::Plane plane(Ogre::Vector3::UNIT_Y, 0);
	Ogre::MeshManager::getSingleton().createPlane("ground", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
        plane, 1500, 1500, 20, 20, true, 1, 5, 5, Ogre::Vector3::UNIT_Z);
	Ogre::Entity* entGround = mSceneMgr->createEntity("GroundEntity", "ground");
    mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(entGround);

    // Set ambient light
    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));

    // Create a light
    Ogre::Light* l = mSceneMgr->createLight("MainLight");
    l->setPosition(20,80,50);

	//create exit button
	MyGUI::ButtonPtr button = mGUI->createWidget<MyGUI::Button>("Button", 10, 10, 300, 26, MyGUI::Align::Default, "Main");
	button->setCaption("exit");

	
	//create texture for camera image
	camImage = Ogre::TextureManager::getSingleton().createManual(
		"CameraImage", // name
		Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
		Ogre::TEX_TYPE_2D,      // type
		320, 240,         // width & height
		0,                // number of mipmaps
		Ogre::PF_B8G8R8A8,     // pixel format
		Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

	//create material from texture
	Ogre::MaterialPtr lMaterial = Ogre::MaterialManager::getSingleton().create("CamMaterial",Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	lMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("CameraImage");
	lMaterial->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
	entGround->setMaterialName("CamMaterial");

	//create myGUI image from material
	image = mGUI->createWidget<MyGUI::StaticImage>("StaticImage", 10, 50, 320, 240, MyGUI::Align::Default, "Main");
	image->setImageTexture("CameraImage");
}

bool GameView::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
	bool ret = BaseApplication::frameRenderingQueued(evt);

	//step the game model
	gameModel->step(evt.timeSinceLastFrame);

	//TODO: testing the move orientation
	ogreNode->setOrientation(gameControl->getMoveOrientation(0));
	ogreNode->yaw(Ogre::Degree(180));
	ogreNode->setPosition(gameControl->getMovePosition(0));

	//showing the camera image of the Eye
	gameControl->copyCameraImageToTexture(camImage);

    return ret;
}

bool GameView::keyPressed( const OIS::KeyEvent &arg )
{
	if (arg.key == OIS::KC_R)   // cycle polygon rendering mode
    {
        Ogre::String newVal;
        Ogre::PolygonMode pm;

        switch (mCamera->getPolygonMode())
        {
        case Ogre::PM_SOLID:
            newVal = "Wireframe";
            pm = Ogre::PM_WIREFRAME;
            break;
        case Ogre::PM_WIREFRAME:
            newVal = "Points";
            pm = Ogre::PM_POINTS;
            break;
        default:
            newVal = "Solid";
            pm = Ogre::PM_SOLID;
        }

        mCamera->setPolygonMode(pm);
    }
    else if(arg.key == OIS::KC_F5)   // refresh all textures
    {
        Ogre::TextureManager::getSingleton().reloadAll();
    }
    else if (arg.key == OIS::KC_SYSRQ)   // take a screenshot
    {
        mWindow->writeContentsToTimestampedFile("screenshot", ".jpg");
    }
    else if (arg.key == OIS::KC_ESCAPE)
    {
        mShutDown = true;
    }

	else if ((arg.key == OIS::KC_J) || (arg.key == OIS::KC_K) || (arg.key == OIS::KC_L) || 
		     (arg.key == OIS::KC_I)|| (arg.key == OIS::KC_O) || (arg.key == OIS::KC_U)  ||
			 (arg.key == OIS::KC_N)|| (arg.key == OIS::KC_M))
		gameControl->PassKeyPressed(arg);

    mGUI->injectKeyPress(MyGUI::KeyCode::Enum(arg.key), arg.text);
    return true;
}

bool GameView::keyReleased( const OIS::KeyEvent &arg )
{
	mGUI->injectKeyRelease(MyGUI::KeyCode::Enum(arg.key));

	if ((arg.key == OIS::KC_J) || (arg.key == OIS::KC_K) || (arg.key == OIS::KC_L) || (arg.key == OIS::KC_I)|| (arg.key == OIS::KC_O) || (arg.key == OIS::KC_U))
		gameControl->PassKeyReleased(arg);

    return true;
}

bool GameView::mouseMoved( const OIS::MouseEvent &arg )
{
	mGUI->injectMouseMove(arg.state.X.abs, arg.state.Y.abs, arg.state.Z.abs);

	gameControl->PassmouseMoved(arg);

    return true;
}